
require "pathname"
require 'rake/clean'

# 请自行定义下面两行
NAME            = "windump" # 可执行文件名
SRC             = "./src" #  D 源程序在 ./src 目录下（包括子目录）
IMPORT_DIR      = "./src"

LIBS = ["advapi32.lib", "uuid.lib", "ole32.lib", "oleaut32.lib"] # 程序用到的附加 .lib
    #

DCFLAGS_DEBUG     = "-debug -g -version=WD_Console"
DCFLAGS_RELEASE   = "-release -O -version=WD_Release " 
DCFLAGS_UNITTEST  = "-debug -g -debug=WD_Unittest -version=WD_Console -unittest"
DCFLAGS_COMMON = "-J#{IMPORT_DIR} -c -I#{IMPORT_DIR} "
LINKFLAGS_GUI = " -L/exet:nt/su:windows:4.0 "
DC         = "dmd.exe" # "call gdmd"

$release = false
$dcflags_var = ""
$linkflags_var = ""

if(ENV["release"])
    $release = true
    $dcflags_var = DCFLAGS_RELEASE
else
    $dcflags_var = DCFLAGS_DEBUG
end

OUTDIR_RELEASE = "./output/release"
OUTDIR_DEBUG = "./output/debug"
OUTDIR_UNITTEST = "./output/unittest"

#  这里定义要编译的文件

SRCS_LIBWINDUMP = [
    './src/windump/common.d',
    './src/windump/combase.d',
    './src/windump/config.d',
    './src/windump/dll.d',
    './src/windump/pathfinder.d',
    './src/windump/registry.d',
    './src/windump/singleton.d',
    './src/windump/utf.d',
    './src/windump/util.d',
    './src/windump/w32api.d',
    './src/windump/wdversion.d',
    './src/windump/scanning/common.d',
    './src/windump/scanning/detector.d',
    './src/windump/scanning/scanner.d',
]

SRCS_PLUGINS = FileList.new('./src/windump/plugins/**/*.d') 
SRCS_WINDUMPD = FileList.new('./src/windumpd/**/*.d') + SRCS_PLUGINS
SRCS_GWINDUMP = FileList.new('./src/gwindump/**/*.d') + SRCS_PLUGINS

SRCS_ALL = SRCS_LIBWINDUMP + SRCS_PLUGINS + SRCS_WINDUMPD + SRCS_GWINDUMP


FILENAME_LIBWINDUMP = "libwindump.lib"
FILENAME_PLUGINS = "plugins.lib"
FILENAME_GWINDUMP = "gwindump.exe"
FILENAME_WINDUMPD = "windumpd.exe"
DIRECTORY_OUTPUT = "./output"
FILENAME_WINDUMPZIP = "#{DIRECTORY_OUTPUT}/windump-bin.zip"
FILENAME_SOURCE = "#{DIRECTORY_OUTPUT}/windump-src.tar.bz2"

PACK_FILES = FileList.new('./doc/**/*') +
    [ FILENAME_GWINDUMP ]


directory "output"
directory OUTDIR_DEBUG
directory OUTDIR_RELEASE
directory OUTDIR_UNITTEST

# 辅助函数

def dolink(target, t, type, appLibs)
    tflag = ""
    case type
    when :lib then tflag = "-lib"
    when :gui then tflag = LINKFLAGS_GUI
    when :console then tflag = ""
    end

    sh "#{DC} #{tflag} -of#{target} #{t.prerequisites.join(' ')} -L+#{LIBS.join('+')} #{appLibs.join(' ')}"
    if $release and type != :lib then
        upx(target)
    end
end

def docompile(src, obj, flags)	
    sh "#{DC} #{$dcflags_var} #{DCFLAGS_COMMON} #{flags} -of#{obj} #{src}"
end

def upx(filename)
    sh "upx --lzma --no-backup -9 #{filename}"
end

rule '.obj' => '.d' do |t|
    docompile(t.source, t.name, "")        
end

task :libwindump => FILENAME_LIBWINDUMP
task :plugins => FILENAME_PLUGINS
task :windumpd => FILENAME_WINDUMPD
task :gwindump => FILENAME_GWINDUMP
task :packexe => FILENAME_WINDUMPZIP
task :packsrc => FILENAME_SOURCE
task :pack => [:packsrc, :packexe]

file FILENAME_LIBWINDUMP => SRCS_LIBWINDUMP.map{ |fn| fn.ext("obj")} do |f|
    dolink(FILENAME_LIBWINDUMP, f, :lib, [])
end

file FILENAME_PLUGINS => SRCS_PLUGINS.map{ |fn| fn.ext("obj")} + [FILENAME_LIBWINDUMP] do |f|
    dolink(FILENAME_PLUGINS, f, :lib, [])
end

file FILENAME_WINDUMPD => SRCS_WINDUMPD.map{ |fn| fn.ext("obj")} \
    + [FILENAME_LIBWINDUMP] do |f|

    dolink(FILENAME_WINDUMPD, f, :console, [])
end

file FILENAME_GWINDUMP => SRCS_GWINDUMP.map{ |fn| fn.ext("obj")} \
    + [FILENAME_LIBWINDUMP] do |f|

    dolink(FILENAME_GWINDUMP, f, :gui, ["dfl.lib"])
end

file FILENAME_WINDUMPZIP => PACK_FILES do |f|
    sh "7z u -tzip #{f.name} #{f.source} #{f.prerequisites.join(' ')}"
end

file FILENAME_SOURCE do |f|
    sh "bzr export #{f.name} #{f.prerequisites.join(' ')}"
end

task :clean do
    rm_f FILENAME_LIBWINDUMP
    rm_f FILENAME_PLUGINS
    rm_f FILENAME_GWINDUMP
    rm_f FILENAME_WINDUMPD
    rm_f FILENAME_WINDUMPD.ext("map")
    rm_f FILENAME_GWINDUMP.ext("map")
    rm_f SRCS_ALL.map {|f| f.ext("obj") }
    rm_f FILENAME_WINDUMPZIP
    rm_f FILENAME_SOURCE
    rm_rf DIRECTORY_OUTPUT
end
